package com.zb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.entity.ZjWorkSpareMaterial;
import com.zb.entity.ZjWorkSpareMaterialAnnex;
import com.zb.entity.ZjWorkSpareMaterialApply;
import com.zb.extend.WorkSpareMaterialExtend;
import com.zb.mapper.ZjWorkSpareMaterialMapper;
import com.zb.service.*;
import com.zb.view.ViewGoods;
import com.zb.vo.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 工单备件物料表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2023-10-26
 */
@Service
public class ZjWorkSpareMaterialServiceImpl extends ServiceImpl<ZjWorkSpareMaterialMapper, ZjWorkSpareMaterial> implements ZjWorkSpareMaterialService {
    @Resource
    private ZjWorkSpareMaterialMapper workSpareMaterialMapper;
    @Resource
    private ZjWorkSpareMaterialApplyService workSpareMaterialApplyService;
    @Resource
    private ZjWorkSpareMaterialAnnexService workSpareMaterialAnnexService;
    @Resource
    private ViewGoodsService viewGoodsService;

    // 新增、修改、删除工单备件
    @Override
    public void save(Long custAccId, Long workId, Long workSpareId, List<WorkSpareMaterialVo> spareMaterialVos, List<Long> ids) {
        if (CollectionUtil.isNotEmpty(ids)) {
            workSpareMaterialApplyService.removeByIds(ids);
            workSpareMaterialAnnexService.deleteByWorkSpareMaterialIds(ids);
            this.removeByIds(ids);
        }
        List<WorkSpareMaterialVo> wsm = spareMaterialVos.stream().filter(f -> null != f.getSpareId() && 0 != f.getSpareId()).toList();
        if (CollectionUtil.isNotEmpty(wsm)) {
            List<Long> spareIds = wsm.stream().map(WorkSpareMaterialVo::getSpareId).distinct().toList();
            List<Long> specIds = wsm.stream().map(WorkSpareMaterialVo::getSpecId).distinct().toList();
            List<ViewGoods> viewGoodsList = viewGoodsService.getByGoodsIdsAndGoodsSpecIds(spareIds, specIds);
            List<WorkSpareMaterialVo> materialVos = wsm.stream().filter(f -> viewGoodsList.stream().noneMatch(fp -> Objects.equals(fp.getId(), f.getSpareId()) && Objects.equals(fp.getSpecId(), f.getSpecId()))).toList();
            if (CollectionUtil.isNotEmpty(materialVos)) {
                StringBuilder builder = new StringBuilder("申请的备件型号与规格[");
                for (WorkSpareMaterialVo vo : materialVos) {
                    builder.append(vo.getModel()).append("、").append(vo.getSpecName()).append("；");
                }
                builder.append("]的备件数据不存在系统中，无法申请备件");
                Assert.isTrue(false, builder.toString());
            }
            spareMaterialVos.forEach(t -> {
                viewGoodsList.stream().filter(f -> Objects.equals(f.getId(), t.getSpareId()) && Objects.equals(f.getSpecId(), t.getSpecId())).findFirst().ifPresent(specView -> {
                    t.setModel(specView.getModel());
                    t.setName(specView.getName());
                    t.setSpecName(specView.getSpecName());
                    t.setSpecSku(specView.getSpecCode());
                });
            });
        }

        QueryWrapper<ZjWorkSpareMaterial> wrapper = new QueryWrapper<>();
        wrapper.select("id", "type", "spare_id", "spec_id", "qty", "price", "pay_network_price", "receive_factory_price");
        wrapper.in("work_spare_id", workSpareId);
        List<ZjWorkSpareMaterial> materialList = this.list(wrapper);
        if (CollectionUtil.isNotEmpty(materialList)) {
            spareMaterialVos.forEach(t -> {
                if (null == t.getId()) {
                    Long id = materialList.stream().filter(f -> f.getOverinsured() == t.getOverinsured() && Objects.equals(f.getType(), t.getType()) &&
                                    Objects.equals(f.getSpareId(), t.getSpareId()) && Objects.equals(f.getSpecId(), t.getSpecId()) &&
                                    f.getPrice().equals(t.getPrice()) && f.getPayNetworkPrice().equals(t.getPayNetworkPrice()) &&
                                    f.getReceiveFactoryPrice().equals(t.getReceiveFactoryPrice()))
                            .map(ZjWorkSpareMaterial::getId).findFirst().orElse(null);
                    if (null != id) {
                        t.setId(id);
                    }
                }
            });
        }
        List<WorkSpareMaterialVo> newSpareMaterialVos = new ArrayList<>(spareMaterialVos.stream().filter(f -> null != f.getId()).toList());
        List<WorkSpareMaterialVo> oldSpareMaterialVos = new ArrayList<>();
        for (WorkSpareMaterialVo vo : spareMaterialVos) {
            if (newSpareMaterialVos.stream().noneMatch(f -> Objects.equals(f.getId(), vo.getId()))) {
                oldSpareMaterialVos.add(vo);
            }
        }
        spareMaterialVos = oldSpareMaterialVos;
        // 去重合并，且相同数量相加
        spareMaterialVos.forEach(t -> {
            WorkSpareMaterialVo materialVo = newSpareMaterialVos.stream().filter(f -> f.getOverinsured() == t.getOverinsured() && Objects.equals(f.getType(), t.getType()) &&
                    Objects.equals(f.getSpareId(), t.getSpareId()) && Objects.equals(f.getSpecId(), t.getSpecId()) && f.getPrice().equals(t.getPrice()) &&
                            f.getPayNetworkPrice().equals(t.getPayNetworkPrice()) && f.getReceiveFactoryPrice().equals(t.getReceiveFactoryPrice()))
                    .findFirst().orElse(null);
            if (null != materialVo) {
                extracted(t, materialVo);
            } else {
                materialVo = newSpareMaterialVos.stream().filter(f -> f.getOverinsured() == t.getOverinsured() && Objects.equals(f.getType(), t.getType()) &&
                        Objects.equals(f.getModel(), t.getModel()) && Objects.equals(f.getSpecName(), t.getSpecName()) && f.getPrice().equals(t.getPrice()) &&
                                f.getPayNetworkPrice().equals(t.getPayNetworkPrice()) && f.getReceiveFactoryPrice().equals(t.getReceiveFactoryPrice()))
                        .findFirst().orElse(null);
                if (null != materialVo) {
                    extracted(t, materialVo);
                } else {
                    newSpareMaterialVos.add(t);
                }
            }
        });
        List<ZjWorkSpareMaterial> adds = new ArrayList<>();
        List<ZjWorkSpareMaterial> updates = new ArrayList<>();
        List<ZjWorkSpareMaterialApply> addsMaterialApplys = new ArrayList<>();
        List<ZjWorkSpareMaterialAnnex> materialAnnexList = new ArrayList<>();
        List<Long> delImageIds = new ArrayList<>();
        ZjWorkSpareMaterial material = null;
        ZjWorkSpareMaterialApply apply = null;
        ZjWorkSpareMaterialAnnex annex = null;
        for (WorkSpareMaterialVo vo : newSpareMaterialVos) {
            material = new ZjWorkSpareMaterial();
            BeanUtil.copyProperties(vo, material);
            if (null != material.getId()) {
                updates.add(material);
                if (CollectionUtil.isNotEmpty(vo.getDelImageIds())) {
                    delImageIds.addAll(vo.getDelImageIds());
                }
            } else {
                material.setId(IdWorker.getId());
                material.setCustAccId(custAccId);
                material.setWorkId(workId);
                material.setWorkSpareId(workSpareId);
                material.setStatus(1);
                material.setStoreId(0L);
                material.setSureUseStatus(0);
                adds.add(material);

                apply = new ZjWorkSpareMaterialApply();
                apply.setId(material.getId());
                apply.setCustAccId(custAccId);
                apply.setWorkId(workId);
                apply.setModel(vo.getModel());
                apply.setName(StringUtils.isNotBlank(vo.getName())? vo.getName() : "");
                apply.setSpec(vo.getSpecName());
                apply.setSpecSku(StringUtils.isNotBlank(vo.getSpecSku())? vo.getSpecSku() : "");
                addsMaterialApplys.add(apply);
            }
            if (CollectionUtil.isNotEmpty(vo.getImages())) {
                for (OrderImageVo image : vo.getImages()) {
                    if (null == image.getId()) {
                        annex = new ZjWorkSpareMaterialAnnex();
                        annex.setId(IdWorker.getId());
                        annex.setCustAccId(custAccId);
                        annex.setWorkId(workId);
                        annex.setWorkSpareMaterialId(material.getId());
                        annex.setImage(image.getImage());
                        materialAnnexList.add(annex);
                    }
                }
            }
        }
        if (CollectionUtil.isNotEmpty(adds)) this.saveBatch(adds);
        if (CollectionUtil.isNotEmpty(updates)) this.updateBatchById(updates);
        if (CollectionUtil.isNotEmpty(addsMaterialApplys)) workSpareMaterialApplyService.saveBatch(addsMaterialApplys);
        if (CollectionUtil.isNotEmpty(materialAnnexList)) workSpareMaterialAnnexService.saveBatch(materialAnnexList);
        if (CollectionUtil.isNotEmpty(delImageIds)) workSpareMaterialAnnexService.removeByIds(delImageIds);
    }

    private static void extracted(WorkSpareMaterialVo t, WorkSpareMaterialVo materialVo) {
        materialVo.setQty(t.getQty() + materialVo.getQty());
        if (StringUtils.isNotBlank(t.getRemark())) {
            if (StringUtils.isNotBlank(materialVo.getRemark())) {
                materialVo.setRemark(materialVo.getRemark() + "；" + t.getRemark());
            } else {
                materialVo.setRemark(t.getRemark());
            }
        }
        if (CollectionUtil.isNotEmpty(t.getImages())) {
            if (CollectionUtil.isNotEmpty(materialVo.getImages())) {
                materialVo.getImages().addAll(t.getImages());
            } else {
                materialVo.setImages(t.getImages());
            }
        }
        if (CollectionUtil.isNotEmpty(t.getDelImageIds())) {
            if (CollectionUtil.isNotEmpty(materialVo.getDelImageIds())) {
                materialVo.getDelImageIds().addAll(t.getDelImageIds());
            } else {
                materialVo.setDelImageIds(t.getDelImageIds());
            }
        }
    }

    // 根据工单备件ID获取备件物料
    @Override
    public List<ZjWorkSpareMaterial> getByWorkSpareIds(List<Long> workSpareIds) {
        if (CollectionUtil.isEmpty(workSpareIds)) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjWorkSpareMaterial> wrapper = new QueryWrapper<>();
        wrapper.select("id", "work_id", "work_spare_id", "status", "type", "spare_id", "spec_id", "qty", "price", "pay_network_price", "receive_factory_price", "sure_use_status");
        wrapper.in("work_spare_id", workSpareIds);
        return this.list(wrapper);
    }


    // 根据备件ID获取关联工单物料的备件
    @Override
    public List<ZjWorkSpareMaterial> getRelationBySpareIds(List<Long> spareIds) {
        if (CollectionUtil.isEmpty(spareIds)) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjWorkSpareMaterial> wrapper = new QueryWrapper<>();
        wrapper.select("spare_id", "spec_id");
        wrapper.in("spare_id", spareIds);
        return this.list(wrapper);
    }

    // 根据备件ID获取关联工单物料的备件
    @Override
    public List<ZjWorkSpareMaterial> getRelationBySpareId(Long spareId) {
        QueryWrapper<ZjWorkSpareMaterial> wrapper = new QueryWrapper<>();
        wrapper.select("spare_id", "spec_id");
        wrapper.eq("spare_id", spareId);
        return this.list(wrapper);
    }

    // 根据仓库ID查询关联工单备件的仓库ID
    @Override
    public List<Long> getRelationByStoreIds(List<Long> storeIds) {
        if (CollectionUtil.isEmpty(storeIds)) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjWorkSpareMaterial> wrapper = new QueryWrapper<>();
        wrapper.select("store_id");
        wrapper.in("store_id", storeIds);
        return this.list(wrapper).stream().map(ZjWorkSpareMaterial::getStoreId).distinct().toList();
    }

    // 根据删除的配件规格ID获取关联工单物料配件的规格ID
    @Override
    public List<Long> getSpecIdsByDelSpecId(List<Long> delSepcIds) {
        if (CollectionUtil.isEmpty(delSepcIds)) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjWorkSpareMaterial> wrapper = new QueryWrapper<>();
        wrapper.select("spec_id")
                .in("spec_id", delSepcIds);
        return this.list(wrapper).stream().map(ZjWorkSpareMaterial::getSpecId).distinct().toList();
    }

    // 根据工单ID获取工单配件导出字段数据
    @Override
    public List<WorkSpareMaterialExtend> getOrderSpareExportFieldByWorkIds(List<Long> workIds) {
        if (CollectionUtil.isEmpty(workIds)) {
            return new ArrayList<>();
        }
        return workSpareMaterialMapper.getOrderSpareExportFieldByWorkIds(workIds);
    }

    // 根据工单ID获取审核通过的配件费用
    @Override
    public ZjWorkSpareMaterial getOrderSettlementFeeByWorkId(Long workId) {
        List<Long> workIds = new ArrayList<>();
        workIds.add(workId);
        List<ZjWorkSpareMaterial> materialList = getOrderSettlementFeeByWorkId(workIds);
        return materialList.size() > 0? materialList.get(0) : null;

    }

    // 根据工单ID获取工单结算费用
    @Override
    public List<ZjWorkSpareMaterial> getOrderSettlementFeeByWorkId(List<Long> workIds) {
        if (CollectionUtil.isEmpty(workIds)) {
            return new ArrayList<>();
        }
        return workSpareMaterialMapper.getOrderSettlementFeeByWorkId(workIds);
    }

    // 根据工单ID获取工单配件费用
    @Override
    public List<WorkSpareMaterialExtend> getByWorkId(Long workId) {
        return workSpareMaterialMapper.getByWorkId(workId);
    }

}
